package pong.game.objects;

import java.nio.IntBuffer;

import javax.microedition.khronos.opengles.GL10;

import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;

public class GL_Helper {

	private static final String TAG = "GL_Helper";
	private static final int BUFFER_SIZE = 262144;// 512x512 = 262144;

	private static final int[] pixels = new int[BUFFER_SIZE];// 1048576

	public static int textureCount = 0;

	// 1024x1024
	// = 1048576

	// private static Bitmap logoSnap;
	// private static Bitmap transparentSnap;
	// private static Bitmap bubbleSnap;
	// protected static Bitmap noImageSnap;
	// private static Bitmap stripeWhiteCircleSnap;
	// private static Bitmap whiteCircleSnap;
	// private static Bitmap stripeGrayCircleSnap;
	// private static Bitmap grayCircleSnap;
	// private static Bitmap redCircleSnap;
	// private static Bitmap background;
	//
	//
	// public static synchronized Bitmap getRedCircleSnap(Context context) {
	// if (redCircleSnap == null) {
	// Bitmap image = null;
	// try {
	// image = BitmapFactory.decodeResource(context.getResources(),
	// R.drawable.circle_stripe_red); // circle_stripe_red
	// // //
	// // bubble_4
	// redCircleSnap = GL_Helper.cropBitmap(image);
	// } finally {
	// recycleBitmap(image);
	// }
	// }
	// return redCircleSnap;
	// }
	//
	// public static synchronized Bitmap getStripeWhiteCircleSnap(Context
	// context) {
	// if (stripeWhiteCircleSnap == null) {
	// Bitmap image = null;
	// try {
	// image = BitmapFactory.decodeResource(context.getResources(),
	// R.drawable.circle_stripe_white);
	// stripeWhiteCircleSnap = GL_Helper.cropBitmap(image);
	// } finally {
	// recycleBitmap(image);
	// }
	// }
	// return stripeWhiteCircleSnap;
	// }
	//
	// public static synchronized Bitmap getWhiteCircleSnap(Context context) {
	// if (whiteCircleSnap == null) {
	// Bitmap image = null;
	// try {
	// image = BitmapFactory.decodeResource(context.getResources(),
	// R.drawable.circle_white);
	// whiteCircleSnap = GL_Helper.cropBitmap(image);
	// } finally {
	// recycleBitmap(image);
	// }
	// }
	// return whiteCircleSnap;
	// }
	//
	// public static synchronized Bitmap getStripeGrayCircleSnap(Context
	// context) {
	// if (stripeGrayCircleSnap == null) {
	// Bitmap image = null;
	// try {
	// image = BitmapFactory.decodeResource(context.getResources(),
	// R.drawable.circle_stripe_gray);
	// stripeGrayCircleSnap = GL_Helper.cropBitmap(image);
	// } finally {
	// recycleBitmap(image);
	// }
	// }
	// return stripeGrayCircleSnap;
	// }
	//
	// public static synchronized Bitmap getGrayCircleSnap(Context context) {
	// if (grayCircleSnap == null) {
	// Bitmap image = null;
	// try {
	// image = BitmapFactory.decodeResource(context.getResources(),
	// R.drawable.circle_gray);
	// grayCircleSnap = GL_Helper.cropBitmap(image);
	// } finally {
	// recycleBitmap(image);
	// }
	// }
	// return grayCircleSnap;
	// }
	//
	// public static synchronized Bitmap getLogoSnap(Context context) {
	// if (logoSnap == null) {
	// Bitmap image = null;
	// try {
	// image = BitmapFactory.decodeResource(context.getResources(),
	// R.drawable.coke_studio_logo);
	// logoSnap = GL_Helper.cropBitmap(image);
	// } finally {
	// recycleBitmap(image);
	// }
	// }
	// return logoSnap;
	// }
	//
	// public static synchronized void resetLogoSnap() {
	// logoSnap.recycle();
	// logoSnap = null;
	// }
	//
	// public static synchronized Bitmap getBubbleSnap(Context context) {
	// if (bubbleSnap == null) {
	// Bitmap image = null;
	// try {
	// image = BitmapFactory.decodeResource(context.getResources(),
	// R.drawable.white_circle_64);
	// bubbleSnap = GL_Helper.cropBitmap(image);
	// } finally {
	// recycleBitmap(image);
	// }
	// }
	// return bubbleSnap;
	// }
	//
	// public static synchronized Bitmap getTransparentSnap(Context context) {
	// if (transparentSnap == null) {
	// Bitmap image = null;
	// try {
	// image = BitmapFactory.decodeResource(context.getResources(),
	// R.drawable.transparentpixel);
	// transparentSnap = GL_Helper.cropBitmap(image);
	// } finally {
	// recycleBitmap(image);
	// }
	// }
	// return transparentSnap;
	// }
	//
	// public static synchronized Bitmap getNoImageSnap(Context context) {
	// if (noImageSnap == null) {
	// Bitmap image = null;
	// try {
	// image = BitmapFactory.decodeResource(context.getResources(),
	// R.drawable.no_image);
	// noImageSnap = GL_Helper.cropBitmap(image);
	// } finally {
	// recycleBitmap(image);
	// }
	// }
	// return noImageSnap;
	// }
	//
	public static void recycleBitmap(Bitmap bitmap) {
		if (bitmap == null) {
			return;
		}
		if (!isStaticBitmap(bitmap)) {
			bitmap.recycle();
		}
	}

	//
	// public static synchronized Bitmap getBackground(Context context) {
	// if (background == null) {
	// Bitmap image = null;
	// try {
	// image = BitmapFactory.decodeResource(context.getResources(),
	// R.drawable.canvas_pattern_grey_1);
	// background = GL_Helper.cropBitmap(image);
	// } finally {
	// recycleBitmap(image);
	// }
	// }
	// return background;
	// }
	//
	public static synchronized boolean isStaticBitmap(Bitmap bitmap) {

		return false;
		// return bitmap == logoSnap || bitmap == noImageSnap || bitmap ==
		// transparentSnap
		// || bitmap == stripeWhiteCircleSnap || bitmap == whiteCircleSnap ||
		// bitmap == stripeGrayCircleSnap
		// || bitmap == grayCircleSnap || bitmap == bubbleSnap // || bitmap
		// // ==
		// // whiteTexture256
		// || bitmap == redCircleSnap; // || bitmap == background;
	}

	//
	// public static void clearBackground() {
	// if (background != null) {
	// background.recycle();
	// background = null;
	// }
	//
	// }

	private static int getOptimalBitmapWidth(int w) {
		// Minimum
		if ((w & (w - 1)) != 0) {
			if (w < 64) {
				w = 32;
			} else if (w < 128) {
				w = 64;
			} else if (w < 256) {
				w = 128;
			} else if (w < 512) {
				w = 256;
			} else if (w < 1024) {
				w = 512;
			} else {
				w = 512;// 1024
			}
		}
		return w;
	}

	/**
	 * Crop bitmap with item
	 * 
	 * @param bitmap
	 *            - source bitmap
	 * @return - result bitmap without transparent fields
	 */
	public static Bitmap cropBitmap(Bitmap bitmap) {
		int w = getOptimalBitmapWidth(bitmap.getWidth());
		if (w != bitmap.getWidth()) {
			return cropBitmap(bitmap, w);
		}
		return bitmap;
	}

	public static Bitmap cropBitmap(Bitmap bitmap, int newSize) {
		if (bitmap == null || bitmap.isRecycled()) {
			Log.e(TAG, "Try to resize null or recycled bitmap");
			return null;
		}

		long startTime = System.currentTimeMillis();
		int cropWidth = bitmap.getWidth();
		int cropHeight = bitmap.getHeight();

		// calculate the scale - in this case = 0.4f
		float scaleWidth = ((float) newSize) / cropWidth;
		float scaleHeight = ((float) newSize) / cropHeight;

		// create a matrix for the manipulation
		Matrix matrix = new Matrix();
		// resize the bit map
		matrix.postScale(scaleWidth, scaleHeight);
		// recreate the new Bitmap
		Bitmap resizedSnapshot = Bitmap.createBitmap(bitmap, 0, 0, cropWidth, cropHeight, matrix, true);

		Log.v(TAG, "height=" + resizedSnapshot.getHeight());
		Log.v(TAG, "width=" + resizedSnapshot.getWidth());
		Log.v(TAG, "Bitmap newSize = " + newSize + " Complited in " + (System.currentTimeMillis() - startTime) + "ms");

		return resizedSnapshot;
	}

	/**
	 * Crop bitmap with item
	 * 
	 * @param snapshot
	 *            - source bitmap
	 * @return - result bitmap without transparent fields
	 */
	public static Bitmap cropBitmap(Drawable bitmap) {

		BitmapDrawable temp = (BitmapDrawable) bitmap;
		return cropBitmap(temp.getBitmap());
	}

	public static int loadGLTexture(GL10 gl, Bitmap bitmap, boolean fastTexture) {
		int result[] = new int[1];
		// Generate one texture pointer...
		gl.glGenTextures(1, result, 0);
		// ...and bind it to our array
		gl.glBindTexture(GL10.GL_TEXTURE_2D, result[0]);

		// Create Nearest Filtered Texture
		if (fastTexture) {
			gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
			gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
		} else {
			gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
			gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
		}

		// Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);

		long time_start = System.currentTimeMillis();
		// Use the Android GLUtils to specify a two-dimensional texture image
		// from our bitmap
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		int size = width * height;
		if (size > BUFFER_SIZE) {
			size = BUFFER_SIZE;
		}

		bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
		for (int i = 0; i < size; i += 1) {
			int argb = pixels[i];
			pixels[i] = argb & 0xff00ff00 | ((argb & 0xff) << 16) | ((argb >> 16) & 0xff);
		}
		gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, width, height, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE,
				IntBuffer.wrap(pixels));

		// GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
		Log.v(TAG, "Time spended for loading texure:" + (System.currentTimeMillis() - time_start) + " ms.");
		// bmp.recycle();
		Log.d(TAG, "TextureID = " + result[0]);
		// Log.d(TAG, "NativeSize = " +
		// android.os.Debug.getNativeHeapAllocatedSize());
		// CommonUtils.logHeap(getClass());
		return result[0];
	}
}
